from matplotlib import pyplot as plt
import numpy as np
from scipy import stats
from  scipy.stats import norm,binom,poisson
'''1、常用的数据分布实现'''

'''正太分布，也成为高斯分布'''
def norm_distribution():
    plt.rcParams["figure.figsize"]=(14,7)
    plt.figure(dpi=100)

    '''
    PDF  概率密度函数（Probability Density Function）  ;
    stats.norm.pdf  norm即为正太分布，norm.pdf 则为画出正态分布中的概率密度函数
    norm 生成的默认是标准正太分布，即 μ = 0,σ = 1，μ表示均值，σ表示标准差
    下面两句画出概率密度函数并对内部进行填充
    '''
    plt.plot(np.linspace(-4,4,100),stats.norm.pdf(np.linspace(-4,4,100)) / np.max(stats.norm.pdf(np.linspace(-3,3,100))),)
    plt.fill_between(np.linspace(-4,4,100),stats.norm.pdf(np.linspace(-4,4,100)) / np.max(stats.norm.pdf(np.linspace(-3,3,100))),alpha=0.5)

    '''CDF  累积概率密度函数（Cumulative Probability Density Function）  将出现的值都相加取来'''
    plt.plot(np.linspace(-4,4,100),stats.norm.cdf(np.linspace(-4,4,100)))
    plt.text(x=-1.5, y=.7, s="pdf (normed)", rotation=65, alpha=.75, weight="bold", color="#008fd5")
    plt.text(x=-.4, y=.5, s="cdf", rotation=55, alpha=.75, weight="bold", color="#fc4f30")
    plt.show()

    '''均值的变化会引起概率分布在X轴上的左右移动，但因为标准差不变，所以概率分布的浮动范围是一样的'''
    # PDF MU = 0
    plt.plot(np.linspace(-4, 4, 100), stats.norm.pdf(np.linspace(-4, 4, 100)))
    plt.fill_between(np.linspace(-4, 4, 100), stats.norm.pdf(np.linspace(-4, 4, 100)), alpha=0.15)
    # PDF MU = 2   指定均值为2
    plt.plot(np.linspace(-4, 4, 100), stats.norm.pdf(np.linspace(-4, 4, 100), loc=2))
    plt.fill_between(np.linspace(-4, 4, 100), stats.norm.pdf(np.linspace(-4, 4, 100), loc=2), alpha=0.15)
    # PDF MU = -2   指定均值为-2
    plt.plot(np.linspace(-4, 4, 100), stats.norm.pdf(np.linspace(-4, 4, 100), loc=-2))
    plt.fill_between(np.linspace(-4, 4, 100), stats.norm.pdf(np.linspace(-4, 4, 100), loc=-2), alpha=0.15)
    plt.show()

    '''
    标准差的大小会影响概率分布的浮动范围，标准差越大，偏离均值的可能性越大
    标准差越小，偏移均值的可能性越小
    峰值最低的为scale = 2，数据偏离均值的可能性最大
    峰值最低的为scale = 0.5, 数据偏离均值的可能性最小，数据都在0附件浮动
    '''
    # PDF scale = 0.5 指定标准差为0.5
    plt.plot(np.linspace(-4, 4, 100), stats.norm.pdf(np.linspace(-4, 4, 100), scale=0.5), )
    plt.fill_between(np.linspace(-4, 4, 100), stats.norm.pdf(np.linspace(-4, 4, 100), scale=0.5), alpha=0.15)
    # PDF scale = 1 指定标准差为1
    plt.plot(np.linspace(-4, 4, 100), stats.norm.pdf(np.linspace(-4, 4, 100), scale=1))
    plt.fill_between(np.linspace(-4, 4, 100), stats.norm.pdf(np.linspace(-4, 4, 100), scale=1), alpha=0.15)
    # PDF scale = 2 指定标准差为2
    plt.plot(np.linspace(-4, 4, 100), stats.norm.pdf(np.linspace(-4, 4, 100), scale=2))
    plt.fill_between(np.linspace(-4, 4, 100), stats.norm.pdf(np.linspace(-4, 4, 100), scale=2), alpha=0.15)
    plt.show()


'''二项式分布'''
def Binomial_Distribution():
    '''PDF,使用binom.pmf 计算离散型随机变量的概率分布，每一次成功的概率为p=0.5，实验总次数为n=20'''
    plt.bar(x=np.arange(20), height=(stats.binom.pmf(np.arange(20), p=0.5, n=20)), width=0.75, alpha=0.75)
    '''CDF binom 概率累加函数，最后的踪迹总是1'''
    plt.plot(np.arange(20), stats.binom.cdf(np.arange(20), p=.5, n=20), color="#fc4f30")
    plt.show()

    '''当每次赢的概率为0.2的时候，打20场球，赢4次的可能性最大，即为np = 0.2 * 20 = 4,
    最大的可能性总是出现在均值附近'''
    plt.scatter(np.arange(21), (stats.binom.pmf(np.arange(21), p=.2, n=20)), alpha=0.75, s=100)
    plt.plot(np.arange(21), (stats.binom.pmf(np.arange(21), p=.2, n=20)), alpha=0.75)
    '''当每次赢的概率为0.5的时候，打20场球，赢10次的可能性最大，即为np=0.5*20=10'''
    plt.scatter(np.arange(21), (stats.binom.pmf(np.arange(21), p=.5, n=20)), alpha=0.75, s=100)
    plt.plot(np.arange(21), (stats.binom.pmf(np.arange(21), p=.5, n=20)), alpha=0.75)
    '''当每次赢的概率为0.9的时候，打20场球，赢18次的可能性最大，即为np=0.9*20=18'''
    plt.scatter(np.arange(21), (stats.binom.pmf(np.arange(21), p=.9, n=20)), alpha=0.75, s=100)
    plt.plot(np.arange(21), (stats.binom.pmf(np.arange(21), p=.9, n=20)), alpha=0.75)
    plt.show()

    '''当实验的次数越多，峰值变矮，因为可能性更多了，数据被分散了'''
    plt.scatter(np.arange(21), (stats.binom.pmf(np.arange(21), p=.5, n=20)), alpha=0.75, s=100)
    plt.plot(np.arange(21), (stats.binom.pmf(np.arange(21), p=.5, n=20)), alpha=0.75)

    plt.scatter(np.arange(21), (stats.binom.pmf(np.arange(21), p=.5, n=30)), alpha=0.75, s=100)
    plt.plot(np.arange(21), (stats.binom.pmf(np.arange(21), p=.5, n=30)), alpha=0.75)

    plt.scatter(np.arange(21), (stats.binom.pmf(np.arange(21), p=.5, n=40)), alpha=0.75, s=100)
    plt.plot(np.arange(21), (stats.binom.pmf(np.arange(21), p=.5, n=40)), alpha=0.75)

    plt.show()

'''泊松分布'''
def Poisson_distribution():
    plt.rcParams["figure.figsize"] = (14, 7)
    plt.figure(dpi=100)
    '''绘制泊松分布的概率密度函数(pdf)和概率累积函数(cdf)'''
    # PDF
    plt.bar(x=np.arange(20),height=(stats.poisson.pmf(np.arange(20), mu=5)),width=.75,alpha=0.75)
    # CDF
    plt.plot(np.arange(20), stats.poisson.cdf(np.arange(20), mu=5),color="#fc4f30")

    '''分别设置µ = λ*t=1,5,10时候的泊松分布曲线，峰值最高的为µ=1，峰值最低的为µ=10，并且峰值都出现在µ的周围，
    有点像正太分布'''
    # PDF LAM = 1
    plt.scatter(np.arange(20), (stats.poisson.pmf(np.arange(20), mu=1)), alpha=0.75, s=100)
    plt.plot(np.arange(20), (stats.poisson.pmf(np.arange(20), mu=1)), alpha=0.75, )
    # PDF LAM = 5
    plt.scatter(np.arange(20),(stats.poisson.pmf(np.arange(20), mu=5)),alpha=0.75,s=100)
    plt.plot(np.arange(20),(stats.poisson.pmf(np.arange(20), mu=5)),alpha=0.75,)

    # PDF LAM = 10
    plt.scatter(np.arange(20), (stats.poisson.pmf(np.arange(20), mu=10)),alpha=0.75,s=100)
    plt.plot(np.arange(20),(stats.poisson.pmf(np.arange(20), mu=10)),alpha=0.75,)

    #输出符合泊松分布的数据
    print(poisson.rvs(mu=10))
    print(poisson.rvs(mu=10, size=10))

    # 绘制泊松分布的散点图，峰值出现在8附近，也就是均值附近
    x_s = np.arange(15)
    y_s = poisson.pmf(k=x_s, mu=8)
    plt.scatter(x_s, y_s, s=100)

    '''# 利用泊松分布计算数据概率
    # probability of x less or equal 0.3'''
    print("P(X <=3) = {}".format(poisson.cdf(k=3, mu=5)))
    # probability of x in [-0.2, +0.2]
    print("P(2 < X <= 8) = {}".format(poisson.cdf(k=8, mu=5) - poisson.cdf(k=2, mu=5)))

    plt.show()

def Chi_Squared_Distribution():

    '''卡方分布的pdf和cdf函数，df表示自由度'''
    # PDF
    plt.plot(np.linspace(0, 20, 100),stats.chi2.pdf(np.linspace(0, 20, 100), df=4) ,)
    plt.fill_between(np.linspace(0, 20, 100),stats.chi2.pdf(np.linspace(0, 20, 100), df=4) ,alpha=.15,)
    # CDF
    plt.plot(np.linspace(0, 20, 100),stats.chi2.cdf(np.linspace(0, 20, 100), df=4),)

    '''自由度的不同对卡方分布的影响,自由度越高，图形越陡峭,df表示自由度'''
    # PDF df = 1
    plt.plot(np.linspace(0, 15, 500),stats.chi2.pdf(np.linspace(0, 15, 500), df=1),)
    plt.fill_between(np.linspace(0, 15, 500),stats.chi2.pdf(np.linspace(0, 15, 500), df=1),alpha=.15,)
    # PDF df = 3
    plt.plot(np.linspace(0, 15, 100), stats.chi2.pdf(np.linspace(0, 15, 100), df=3),)
    plt.fill_between(np.linspace(0, 15, 100),stats.chi2.pdf(np.linspace(0, 15, 100), df=3),alpha=.15,)
    # PDF df = 6
    plt.plot(np.linspace(0, 15, 100),stats.chi2.pdf(np.linspace(0, 15, 100), df=5),)
    plt.fill_between(np.linspace(0, 15, 100),stats.chi2.pdf(np.linspace(0, 15, 100), df=6),alpha=.15,)
    plt.show()


if __name__ == '__main__':
    Chi_Squared_Distribution()